using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using AdminSG3L.Domain.Entities;

namespace AdminSG3L.Domain.Repositories;

public interface IRepository<T> where T : EntityBase
{
    /// <summary>
    /// 分页查询数据。
    /// </summary>
    /// <param name="predicate">查询条件表达式</param>
    /// <param name="pageIndex">页码（从0开始）</param>
    /// <param name="pageSize">每页数据量</param>
    /// <returns>返回分页后的数据集合和总数</returns>
    Task<(IEnumerable<T> Items, int TotalCount)> GetPagedAsync(
        Expression<Func<T, bool>> predicate,
        int pageIndex,
        int pageSize);

    /// <summary>
    /// 根据条件查询一条数据。
    /// </summary>
    /// <param name="predicate">查询条件表达式</param>
    /// <returns>返回符合条件的单个实体，查不到时返回null</returns>
    Task<T?> GetSingleAsync(Expression<Func<T, bool>> predicate);

    /// <summary>
    /// 根据条件查询多条数据。
    /// </summary>
    /// <param name="predicate">查询条件表达式</param>
    /// <returns>返回符合条件的实体集合</returns>
    Task<IEnumerable<T>> GetManyAsync(Expression<Func<T, bool>> predicate);

    /// <summary>
    /// 批量添加实体。
    /// </summary>
    /// <param name="entities">要添加的实体集合</param>
    Task AddRangeAsync(IEnumerable<T> entities);

    /// <summary>
    /// 批量删除实体。
    /// </summary>
    /// <param name="entities">要删除的实体集合</param>
    Task DeleteRangeAsync(IEnumerable<T> entities);

    /// <summary>
    /// 根据条件获取数据条数。
    /// </summary>
    /// <param name="predicate">查询条件表达式</param>
    /// <returns>返回符合条件的数据条数</returns>
    Task<int> CountAsync(Expression<Func<T, bool>> predicate);

    /// <summary>
    /// 获取所有数据的总数。
    /// </summary>
    /// <returns>返回所有数据的总条数</returns>
    Task<int> CountAllAsync();

    /// <summary>
    /// 根据主键获取实体。
    /// </summary>
    /// <param name="id">主键Id</param>
    /// <returns>返回实体对象，查不到时返回null</returns>
    Task<T?> GetByIdAsync(Guid id);

    /// <summary>
    /// 获取所有实体。
    /// </summary>
    /// <returns>返回所有实体集合</returns>
    Task<IEnumerable<T>> GetAllAsync();

    /// <summary>
    /// 添加单个实体。
    /// </summary>
    /// <param name="entity">要添加的实体</param>
    Task AddAsync(T entity);

    /// <summary>
    /// 更新单个实体。
    /// </summary>
    /// <param name="entity">要更新的实体</param>
    Task UpdateAsync(T entity);

    /// <summary>
    /// 删除单个实体。
    /// </summary>
    /// <param name="entity">要删除的实体</param>
    Task DeleteAsync(T entity);
}